package com.itzdm.common.advice;

import com.itzdm.common.result.Result;
import com.itzdm.common.constant.MessageConstant;
import com.itzdm.common.exception.BadRequestException;
import com.itzdm.common.exception.CommonException;
import com.itzdm.common.exception.DbException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.util.NestedServletException;

import java.net.BindException;
import java.util.stream.Collectors;

@RestControllerAdvice
@Slf4j
public class CommonExceptionAdvice {

    @ExceptionHandler(BadRequestException.class)
    public Result<?> handleBadRequestException(BadRequestException e) {
        log.error("请求参数错误: {}", e.getMessage());
        return Result.error(e.getMessage());
    }

    @ExceptionHandler(DbException.class)
    public Result<?> handleDbException(DbException e) {
        log.error("数据库操作异常", e);
        return Result.error(MessageConstant.MYSQL_ERROR);
    }

    @ExceptionHandler(CommonException.class)
    public Result<?> handleCommonException(CommonException e) {
        log.error("自定义异常: {}", e.getMessage(), e);
        return Result.error(e.getMessage());
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result<?> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        String supportedMethods = e.getSupportedHttpMethods().stream()
            .map(method -> method.name())
            .collect(Collectors.joining(", "));
        String message = String.format("不支持的请求方法: %s, 支持的方法: %s", 
            e.getMethod(), 
            supportedMethods);
        log.error(message);
        return Result.error(message);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        String msg = e.getBindingResult().getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.joining("|"));
        log.error("请求参数校验异常: {}", msg, e);
        return Result.error(msg);
    }

    @ExceptionHandler(BindException.class)
    public Result<?> handleBindException(BindException e) {
        log.error("请求参数绑定异常", e);
        return Result.error("请求参数格式错误");
    }

    @ExceptionHandler(NestedServletException.class)
    public Result<?> handleNestedServletException(NestedServletException e) {
        log.error("参数处理异常", e);
        return Result.error("请求参数处理异常");
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public Result<?> handleIllegalArgumentException(IllegalArgumentException e) {
        log.error("参数非法: {}", e.getMessage());
        return Result.error(e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Result<?> handleException(Exception e) {
        log.error("服务器内部异常", e);
        return Result.error(MessageConstant.UNKNOWN_ERROR);
    }

}
